package cn.kys.modules.system.service.impl;


import cn.hutool.json.JSONUtil;
import cn.kys.common.utils.*;
import cn.kys.modules.security.security.vo.JwtUser;
import cn.kys.modules.system.domain.GeomEntity;
import cn.kys.modules.system.pojo.SubtaskGeom;
import cn.kys.modules.system.repository.ToolsResposity;
import cn.kys.modules.system.service.MobileService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.GridFSFindIterable;
import com.mongodb.client.gridfs.model.GridFSFile;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.ibatis.annotations.Select;
import org.apache.poi.ss.formula.functions.T;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.io.WKTReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.apache.commons.codec.binary.Base64;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class MobileServiceImpl implements MobileService {
    @Value("${file.shpUpdate}")
    private String shpUpdate;

    @Autowired
    private ToolsResposity toolsResposity;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    GridFsTemplate gridFsTemplate;


    @Autowired
    private UserDetailsService userDetailsService;

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

    @Override
    public List getTasks() {

        List list = new ArrayList();
        JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(SecurityUtils.getUsername());
        Long userid = jwtUser.getId();
        String sql = "SELECT * FROM public.t_task where id in (SELECT taskid FROM public.t_subtask where userid = " + userid + " and status = '已开始') and status !='未开始'";
        List listTask = toolsResposity.exeSqlList(sql);
        for (int i = 0; i < listTask.size(); i++) {
            Map taskMap = (Map) listTask.get(i);
            int taskId = Integer.parseInt(taskMap.get("id").toString());
            String sql_subtask = "SELECT * FROM public.t_subtask where taskid = " + taskId + " and userid = " + userid;
            Map subTaskMap = toolsResposity.exeSql(sql_subtask);
            String status = subTaskMap.get("status").toString();
            taskMap.put("subtaskStatus", status);
            list.add(taskMap);
        }
        return list;
    }

    @Override
    public List getTasksPC() {
        List list = new ArrayList();
        JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(SecurityUtils.getUsername());
        Long userid = jwtUser.getId();
        String sql = "SELECT * FROM public.t_task where id in (SELECT taskid FROM public.t_subtask where userid = " + userid + " ) and status !='未开始'";
        List listTask = toolsResposity.exeSqlList(sql);
        for (int i = 0; i < listTask.size(); i++) {
            Map taskMap = (Map) listTask.get(i);
            int taskId = Integer.parseInt(taskMap.get("id").toString());
            String sql_subtask = "SELECT * FROM public.t_subtask where taskid = " + taskId + " and userid = " + userid;
            Map subTaskMap = toolsResposity.exeSql(sql_subtask);
            String status = subTaskMap.get("status").toString();
            taskMap.put("subtaskStatus", status);
            list.add(taskMap);
        }
        return list;
    }


    @Override
    public void submitTableContent(String subtaskid, String edit_geoid, String status, String content) {
        JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(SecurityUtils.getUsername());
        Long userid = jwtUser.getId();
        //保存内容到mongodb
        try {
            //存储表单信息
            Criteria criteria = Criteria.where("metadata.globle_subtaskid").is(subtaskid);
            criteria.and("metadata.globle_edit_geoid").is(edit_geoid);
            criteria.and("metadata.globle_userid").is(userid);
            Query query = new Query(criteria);
            boolean existed = mongoTemplate.exists(query, JSONObject.class, "tableEntity");

            if (existed) {
                //删除原来的
                mongoTemplate.findAllAndRemove(query, JSONObject.class, "tableEntity");
            }
            JSONObject jsonObject = (JSONObject) JSON.parse(content);

            Map metadata = new HashMap<>();
            metadata.put("globle_userid", userid);
            metadata.put("globle_subtaskid", subtaskid);
            metadata.put("globle_edit_geoid", edit_geoid);
            metadata.put("globle_status", status);

            jsonObject.put("metadata", metadata);

            mongoTemplate.save(jsonObject, "tableEntity");


        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private List filterList(List list) {

        List returnList = new ArrayList();

        for (int i = 0; i < list.size(); i++) {
            Map returnMap = (Map) list.get(i);

            String st_astext = returnMap.get("polygon").toString();

            List listPolygon = new ArrayList();

            if (st_astext.contains("MULTIPOLYGON")) {
                st_astext = st_astext.substring(16, st_astext.length() - 3);
            } else {
                st_astext = st_astext.substring(9, st_astext.length() - 2);
            }

            String[] polygons = st_astext.split("\\)\\), \\(\\(");

            for (int j = 0; j < polygons.length; j++) {
                String polygon = polygons[j].trim();
                if (polygon.contains("),(")) {
                    String[] polygonHole = polygon.split("\\),\\(");
                    listPolygon.add(polygonHole);
                } else {
                    listPolygon.add(polygon);
                }
            }

            returnMap.put("geo", listPolygon);

            returnList.add(returnMap);
        }

        return returnList;

    }

    @Override
    public String submitTableFile(String subtaskid, String globle_edit_geoid, String formcontentname, MultipartFile uploadFile, String alpha
            , String beta
            , String gamma
            , String lat
            , String lon) {
        String filename = null;
        JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(SecurityUtils.getUsername());
        Long userid = jwtUser.getId();
        try {
            //获取文件名
            String fileName = uploadFile.getOriginalFilename();
            //获取文件后缀名
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            //重新生成文件名
            fileName = UUID.randomUUID() + suffixName;
            //添加日期目录
            String format = sdf.format(new Date());
            //指定本地文件夹存储图片
            String filePath = "D:/images/" + format + "/";
            File file = new File(filePath, fileName);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            try {
                //图片保存
                file.createNewFile();
                uploadFile.transferTo(new File(filePath + fileName));
                filename = saveFile(file, UUIDStringUtil.getUUIDString(), formcontentname, userid + "", subtaskid, globle_edit_geoid, alpha, beta, gamma, lat, lon);

            } catch (Exception e) {
                e.printStackTrace();

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return filename;
    }

    @Override
    public void updatePhotoInMongoDb(String filename, String alpha, String beta, String gamma, String lat, String lon) {

    }

    @Override
    public String submitVideoFile(String subtaskid, String globle_edit_geoid, String formcontentname, MultipartFile[] uploadFile) {
        return null;
    }

//    @Override
//    public String submitVideoFile(String subtaskid, String globle_edit_geoid, String formcontentname, MultipartFile uploadFile) {
//        return null;
//    }


    @Override
    public Map createGeomPG(String subtaskid, String polygon, String taskid) {

        Map returnMap = new HashMap();

        String sql = "SELECT layername FROM public.t_case_editlayer where caseid in (select caseid from t_task where id = '" + taskid + "')";
        Map map = toolsResposity.exeSql(sql);
        String layername = map.get("layername").toString();


        polygon = "MULTIPOLYGON(((" + polygon + ")))";
        String geom_text = "st_geomfromtext('" + polygon + "'" + ",4490)";


        //判断新增的polygon是否在 指定的范围内，如果在则插入数据库，并给出提示，如果不在返回相关信息
        String sql_polygon = "SELECT polygon FROM public.t_subtask_polygon where subtaskid = '" + subtaskid + "'";
        Map map_polygon = toolsResposity.exeSql(sql_polygon);
        String multiPolygonExtent_str = map_polygon.get("polygon").toString();

        boolean isIn = true;
        try {
            GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
            WKTReader reader = new WKTReader(geometryFactory);
            MultiPolygon multiPolygonExtent = (MultiPolygon) reader.read(multiPolygonExtent_str);
            MultiPolygon multiPolygonInput = (MultiPolygon) reader.read(polygon);
            if (multiPolygonExtent.contains(multiPolygonInput)) {
                isIn = true;
            } else {
                isIn = false;
            }
        } catch (Exception e) {
            isIn = false;
        }


        if (isIn) {
            String sql_insert_geom = "INSERT INTO public.t_subtask_geom(subtaskid,layername,iscreated,geom,taskid) VALUES (" + subtaskid + ",'" + layername + "'," + true + "," + geom_text + ",'" + taskid + "');";
            toolsResposity.exeSql(sql_insert_geom);
            returnMap.put("success", true);
        } else {

            returnMap.put("success", false);
            returnMap.put("msg", "新绘制的图斑，不在作业区！");
        }

        return returnMap;
    }

    @Override
    public void createGeomMongodb(String subtaskid, String polygon, String taskid) {
        String sql = "SELECT layername FROM public.t_case_editlayer where caseid in (select caseid from t_task where id = '" + taskid + "')";
        Map map = toolsResposity.exeSql(sql);
        String layername = map.get("layername").toString();

        GeomEntity geomEntity = new GeomEntity();
        geomEntity.setCreated(true);
        geomEntity.setSubtaskid(Integer.parseInt(subtaskid));
        geomEntity.setLayername(layername);
        Map geomMap = new HashMap();

        geomMap.put("type", "new");
        geomMap.put("gid", subtaskid + "_" + System.currentTimeMillis());
        geomMap.put("polygon", polygon);
        geomEntity.setNewGeom(geomMap);
        mongoTemplate.save(geomEntity);
    }

    @Override
    public void updateGeomMongoDB(String gid, String polygon) {
        Query query = new Query();
        query.addCriteria(Criteria.where("newGeom.gid").is(gid));

        Update update = new Update();
        update.set("newGeom.polygon", polygon);
        mongoTemplate.upsert(query, update, "geomEntity");
    }

    @Override
    public List queryVideoFile(String subtaskid, String globle_edit_geoid) {
        return null;
    }


    @Override
    public Map updateGeomPG(String subtaskid, String edit_geoid, String polygon) {
        Map returnMap = new HashMap();
        //判断新增的polygon是否在 指定的范围内，如果在则插入数据库，并给出提示，如果不在返回相关信息
        String sql_polygon = "SELECT polygon FROM public.t_subtask_polygon where subtaskid = '" + subtaskid + "'";
        Map map_polygon = toolsResposity.exeSql(sql_polygon);
        String multiPolygonExtent_str = map_polygon.get("polygon").toString();

        polygon = "MULTIPOLYGON(((" + polygon + ")))";
        boolean isIn = true;
        try {
            GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
            WKTReader reader = new WKTReader(geometryFactory);
            MultiPolygon multiPolygonExtent = (MultiPolygon) reader.read(multiPolygonExtent_str);
            MultiPolygon multiPolygonInput = (MultiPolygon) reader.read(polygon);
            if (multiPolygonExtent.contains(multiPolygonInput)) {
                isIn = true;
            } else {
                isIn = false;
            }
        } catch (Exception e) {
            isIn = false;
            returnMap.put("success", false);
            returnMap.put("msg", e.toString());
            return returnMap;
        }

        if (isIn) {

            String geom_text = "st_geomfromtext('" + polygon + "'" + ",4490)";
            String sql_update = "UPDATE public.t_subtask_geom SET  geom=" + geom_text + " WHERE id= " + edit_geoid;
            toolsResposity.exeSql(sql_update);
            returnMap.put("success", true);
        } else {

            returnMap.put("success", false);
            returnMap.put("msg", "新绘制的图斑，不在作业区！");
        }

        return returnMap;


    }

    @Override
    public List queryTableFile(String subtaskid, String edit_geoid) {
        List returnList = new ArrayList();

        String base64 = null;
        JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(SecurityUtils.getUsername());
        Long userid = jwtUser.getId();
        String s = "";
        try {
            //根据id查询文件metadata.globle_gid
            Criteria criteria = Criteria.where("metadata.globle_subtaskid").is(subtaskid);
            criteria.and("metadata.globle_edit_geoid").is(edit_geoid);
            criteria.and("metadata.globle_userid").is(userid + "");
            Query query = new Query(criteria);
            GridFSFindIterable gridFSFiles =
                    gridFsTemplate.find(query);


            for (GridFSFile gridFSFile : gridFSFiles) {
                Map returnMap = new HashMap();
                Document metadataDocument = gridFSFile.getMetadata();

                String formcontentname = metadataDocument.get("globle_formcontentname").toString();
                String filename = metadataDocument.get("filename").toString();

                MongoDatabase mongoDatabase = mongoTemplate.getDb();
                GridFSBucket gridFSBucket = GridFSBuckets.create(mongoDatabase);
                //打开流下载对象
                GridFSDownloadStream downloadStream =
                        gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
                //获取流对象
                GridFsResource gridFsResource = new GridFsResource(gridFSFile, downloadStream);


                //添加日期目录
                String format = sdf.format(new Date());
                //指定本地文件夹存储图片
                String filePathDir = "D:/images/" + format;
                File fileDir = new File(filePathDir);
                String filePath = "D:/images/" + format + "/1.jpg";
                File targetFile = new File(filePath);
                FileUtils.copyInputStreamToFile(gridFsResource.getInputStream(), targetFile);

                try {
                    base64 = convertFileToBase64(filePath);
                    returnMap.put("image", base64);
                    returnMap.put("formcontentname", formcontentname);
                    returnMap.put("filename", filename);
                    returnList.add(returnMap);
                    targetFile.delete();
                    fileDir.delete();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println("打印文件:" + s);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnList;
    }

    @Override
    public List queryTableFileByCjy(String subtaskid, String edit_geoid) {
        return null;
    }


    @Override
    public void deleteTableFile(String subtaskid, String filename) {
        Criteria criteria = Criteria.where("metadata.globle_subtaskid").is(subtaskid);
        criteria.and("metadata.filename").is(filename);
        Query query = new Query(criteria);
        gridFsTemplate.delete(query);
    }

    @Override
    public Map deleteGeomById(String edit_geoid, String subtaskid) {

        Map returnMap = new HashMap();

        JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(SecurityUtils.getUsername());
        Long userid = jwtUser.getId();

        Criteria criteria = Criteria.where("metadata.globle_subtaskid").is(subtaskid);
        criteria.and("metadata.globle_edit_geoid").is(edit_geoid + "");
        criteria.and("metadata.globle_userid").is(Integer.parseInt(userid + ""));
        Query query1 = new Query(criteria);
        JSONObject jsonObject = mongoTemplate.findOne(query1, JSONObject.class, "tableEntity");
        if (jsonObject != null) {
            //不能删除
            returnMap.put("canDelete", false);
            returnMap.put("msg", "存在表单使用该图斑，无法删除！");
        } else {
            //可以删除
            returnMap.put("canDelete", true);
            String sql_delete = "delete from t_subtask_geom where id = " + edit_geoid;
            toolsResposity.exeSql(sql_delete);
        }
        return returnMap;
    }

    @Override
    public Map deleteGeomAndTableById(String edit_geoid, String subtaskid) {
        Map returnMap = new HashMap();

        JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(SecurityUtils.getUsername());
        Long userid = jwtUser.getId();
        //删除表单
        Criteria criteria = Criteria.where("metadata.globle_subtaskid").is(subtaskid);
        criteria.and("metadata.globle_edit_geoid").is(edit_geoid + "");
        criteria.and("metadata.globle_userid").is(Integer.parseInt(userid + ""));
        Query query1 = new Query(criteria);
        mongoTemplate.findAndRemove(query1, JSONObject.class, "tableEntity");

        //删除图斑
        String sql_delete = "delete from t_subtask_geom where id = " + edit_geoid;
        toolsResposity.exeSql(sql_delete);

        //删除文件
        Criteria criteriaFile = Criteria.where("metadata.globle_subtaskid").is(subtaskid);
        criteriaFile.and("metadata.globle_edit_geoid").is(edit_geoid);
        Query query = new Query(criteriaFile);
        gridFsTemplate.delete(query);

        return returnMap;
    }

    /**
     * 本地文件（图片、excel等）转换成Base64字符串
     *
     * @param imgPath
     */
    public String convertFileToBase64(String imgPath) {
        byte[] data = null;
        // 读取图片字节数组
        try {
            InputStream in = new FileInputStream(imgPath);
            System.out.println("文件大小（字节）=" + in.available());
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组进行Base64编码，得到Base64编码的字符串
//        BASE64Encoder encoder = new BASE64Encoder();
//        String base64Str = encoder.encode(data);
        return Base64.encodeBase64String(data);
    }

    @Override
    public Map getSubTasksPG(String taskid, String caseid) {

        JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(SecurityUtils.getUsername());
        Long userid = jwtUser.getId();

        //select layerid from t_case_layer where caseid in (select caseid from t_task where id = sss)
        Map returnMap = new HashMap();
        List subList = new ArrayList();
        String sql = "select * from t_subtask where taskid in (" + taskid + ") and userid = " + userid;
        List subtaskList = toolsResposity.exeSqlList(sql);
        for (int i = 0; i < subtaskList.size(); i++) {
            Map subTaskMap = (Map) subtaskList.get(i);
            String subtaskid = subTaskMap.get("id").toString();
            //查询范围pg
            String polygonSql = "SELECT * FROM public.t_subtask_polygon where subtaskid = '" + subtaskid + "'";
            List listExtent = toolsResposity.exeSqlList(polygonSql);
            subTaskMap.put("extent", filterList(listExtent));
            //查询相交图斑mongodb
            String subtask_geom_sql = "SELECT *,st_astext(geom) FROM public.t_subtask_geom where subtaskid = '" + subtaskid + "'";
            List listGeom = toolsResposity.exeSqlList(subtask_geom_sql);
            List listGeomAndTable = new ArrayList();
            List listNewGeomAndTable = new ArrayList();//新的图斑
            for (int j = 0; j < listGeom.size(); j++) {
                Map geomEntity = (Map) listGeom.get(j);
                String edit_geoid = geomEntity.get("id").toString();
                boolean isCreated = (boolean) geomEntity.get("iscreated");
                //原来就有的图斑

                Criteria criteria = Criteria.where("metadata.globle_subtaskid").is(subtaskid);
                criteria.and("metadata.globle_edit_geoid").is(edit_geoid + "");
                criteria.and("metadata.globle_userid").is(Integer.parseInt(userid + ""));
                Query query1 = new Query(criteria);
                JSONObject jsonObject = mongoTemplate.findOne(query1, JSONObject.class, "tableEntity");
                if (jsonObject != null) {
                    System.out.println(jsonObject.toJSONString());
                }
                geomEntity.put("table", jsonObject);
                listGeomAndTable.add(geomEntity);


            }

            subTaskMap.put("editPolygon", transToWkt(listGeomAndTable));
            //subTaskMap.put("newPolygon",listNewGeomAndTable);
            subList.add(subTaskMap);
        }

        //baselayer
        String layerBaseSql = "select * from t_layer where id in (select layerid from t_case_baselayer where caseid = '" + caseid + "')";
        List layerBaseList = toolsResposity.exeSqlList(layerBaseSql);
        //speciallayer
        String layerSpecialSql = "select * from t_layer where id in (select layerid from t_case_speciallayer where caseid = '" + caseid + "')";
        List layerSpecialList = toolsResposity.exeSqlList(layerSpecialSql);

        //editlayer
        String layerEditSql = "select * from t_layer where id in (select layerid from t_case_editlayer where caseid = '" + caseid + "')";
        List layerEditList = toolsResposity.exeSqlList(layerEditSql);

        returnMap.put("subtask", subList);
        returnMap.put("baselayers", layerBaseList);
        returnMap.put("speciallayers", layerSpecialList);
        returnMap.put("editlayers", layerEditList);
        return returnMap;
    }

    @Override
    public Map getDetail(String edit_geoid) {
        String sql_search = "select * from t_subtask_geom where id = '" + edit_geoid + "'";
        Map geomEntity = toolsResposity.exeSql(sql_search);
        String gid = geomEntity.get("gid").toString();
        String layername = geomEntity.get("layername").toString();
        String sql = "select * from " + layername + " where id = '" + gid + "'";
        Map orgTable = toolsResposity.exeSql(sql);
        return orgTable;
    }
    /**
     * @return
     * @Author zhaoxw
     * @Description //  原有接口 依赖GDAL 改geotools形式  不依赖于环境
     * @Date 13:26 2024/2/22
     **/
    @Override
    public void exportGPSShp(HttpServletRequest request, HttpServletResponse response, String subtaskid, String date_start, String date_end) {
        String sql = "select * from t_gps t where subtaskid = " + subtaskid + " and (create_time between " + date_start + " and " + date_end + ")";
//        String sql = "select * from t_gps t where subtaskid = " + subtaskid by creat_time  asc;
        List list = toolsResposity.exeSqlList(sql);
        Long startTs = System.currentTimeMillis();
        String shpPointName = startTs + "point.shp";
        String shpLineName = startTs + "line.shp";
        String shpFile = shpUpdate;
        File fileFolder = new File(shpFile);
        if (!fileFolder.isDirectory()) {
            fileFolder.mkdirs();
        }
        ShpWriter.createPointShp(list, shpFile + shpPointName);
        ShpWriter.createLineShp(list, shpFile + shpLineName);
        //压缩
        try {
            //遍历shp 压缩
            File file = new File(shpFile);        //获取其file对象
            File[] fs = file.listFiles();    //遍历path下的文件和目录，放在File数组中
            List<String> sourceFilePaths = new ArrayList<String>();
            for (File f : fs) {                    //遍历File[]数组
                if (f.getPath().contains(startTs + "")) {
                    sourceFilePaths.add(f.getAbsolutePath());
                }
            }
            String zipName = startTs + ".zip";
            String zipTempFilePath = shpFile + zipName;
            //调用压缩
            int s = Zip.compress(sourceFilePaths, zipTempFilePath, false);
            System.out.println("成功压缩" + s + "个文件");

            //上传
            File upFile = new File(zipTempFilePath);
            FileUtil.downloadFileAndDelete(request, response, upFile, true);

            //删除shp数据
            for (File f : fs) {                    //遍历File[]数组
                if (f.getPath().contains(startTs + "")) {

                    File tempFile = new File(f.getAbsolutePath());
                    tempFile.delete();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void exportGPSShp(HttpServletRequest request, HttpServletResponse response, String subtaskid) {
        String sql = "select * from t_gps t where subtaskid = " + subtaskid;
        List list = toolsResposity.exeSqlList(sql);
        Long startTs = System.currentTimeMillis();
        String shpPointName = startTs + "point.shp";
        String shpLineName = startTs + "line.shp";
        String shpFile = shpUpdate;
        ShpWriter.WriteVectorFile(list, shpFile + shpPointName);
        ShpWriter.WriteVectorLineFile(list, shpFile + shpLineName);
        //压缩
        try {
            //遍历shp 压缩
            File file = new File(shpFile);        //获取其file对象
            File[] fs = file.listFiles();    //遍历path下的文件和目录，放在File数组中
            List<String> sourceFilePaths = new ArrayList<String>();
            for (File f : fs) {                    //遍历File[]数组
                if (f.getPath().contains(startTs + "")) {
                    sourceFilePaths.add(f.getAbsolutePath());
                }
            }
            String zipName = startTs + ".zip";
            String zipTempFilePath = shpFile + zipName;
            //调用压缩
            int s = Zip.compress(sourceFilePaths, zipTempFilePath, false);
            System.out.println("成功压缩" + s + "个文件");

            //上传
            File upFile = new File(zipTempFilePath);
            FileUtil.downloadFileAndDelete(request, response, upFile, true);

            //删除shp数据
            for (File f : fs) {                    //遍历File[]数组
                if (f.getPath().contains(startTs + "")) {

                    File tempFile = new File(f.getAbsolutePath());
                    tempFile.delete();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void addGPS(String nickname, String create_time, String userid, String username, String taskid, String taskname, String subtaskid, String lat, String lon) {
        String sql_insert_geom = "INSERT INTO public.t_gps(nickname,create_time,userid,username,taskid,taskname,subtaskid,lat,lon) VALUES ('" + nickname + "','" + create_time + "'," + userid + ",'" + username + "'," + taskid + ",'" + taskname + "'," + subtaskid + ",'" + lat + "','" + lon + "');";
        toolsResposity.exeSql(sql_insert_geom);
    }

    @Override
    public Map getTimeSpan(String subtaskid) {
        Map map = new HashMap();
        String sql_search1 = "SELECT min(create_time) FROM public.t_gps where subtaskid = " + subtaskid;
        Map map1 = toolsResposity.exeSql(sql_search1);

        String sql_search2 = "SELECT max(create_time) FROM public.t_gps where subtaskid = " + subtaskid;
        Map map2 = toolsResposity.exeSql(sql_search2);

        map.put("min", map1.get("min").toString());
        map.put("max", map2.get("max").toString());
        return map;
    }

    @Override
    public List getGPSByTime(String subtaskid, String minTime, String maxTime) {
        String sql_search = "SELECT * FROM public.t_gps where subtaskid = " + subtaskid + " and create_time >= '" + minTime + "' and create_time <= '" + maxTime + "'";
        List list = toolsResposity.exeSqlList(sql_search);
        return list;
    }

    @Override
    public void syncData(String taskid, String caseid) {
        //-1、查询编辑的图层
        //0、根据caseid查找表单结构
        //1、查询t_subtask_geom表中的数据，找到gid。2、根据gid查找获取id值，去mongodb中查找

        //-1
        String sql_case_editlayer = "SELECT * FROM public.t_case_editlayer where caseid = '" + caseid + "'";
        Map case_editlayerMap = toolsResposity.exeSql(sql_case_editlayer);
        String layername = case_editlayerMap.get("layername").toString();
        //0
        String sql_search = "SELECT * FROM public.t_form_content where formid in (SELECT formid FROM public.t_case_form where caseid = '" + caseid + "')";
        List form_content_list = toolsResposity.exeSqlList(sql_search);

        //1
        String sql_geom_search = "SELECT id,gid FROM public.t_subtask_geom where taskid = '" + taskid + "'";
        List id_list = toolsResposity.exeSqlList(sql_geom_search);

        for (int i = 0; i < form_content_list.size(); i++) {
            Map map = (Map) form_content_list.get(i);
            String formcontentname = map.get("formcontentname").toString();
            String type = map.get("type").toString();

            if ("图片_普通".equals(type)) {
                //是图片

                String s = "";
                for (int j = 0; j < id_list.size(); j++) {
                    Map mapIds = (Map) id_list.get(j);
                    String id = mapIds.get("id").toString();//mongodb中的globle_edit_geoid
                    String gid = mapIds.get("gid").toString();//t_subtask_geom中的gid也是sick_tree中的id

                    try {
                        //根据id查询文件metadata.globle_gid
                        Criteria criteria = Criteria.where("metadata.globle_edit_geoid").is(id);
                        Query query = new Query(criteria);
                        GridFSFindIterable gridFSFiles =
                                gridFsTemplate.find(query);


                        for (GridFSFile gridFSFile : gridFSFiles) {
                            Map returnMap = new HashMap();
                            Document metadataDocument = gridFSFile.getMetadata();

                            String formcontentname_ = metadataDocument.get("globle_formcontentname").toString();
                            String filename = metadataDocument.get("filename").toString();

                            MongoDatabase mongoDatabase = mongoTemplate.getDb();
                            GridFSBucket gridFSBucket = GridFSBuckets.create(mongoDatabase);
                            //打开流下载对象
                            GridFSDownloadStream downloadStream =
                                    gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
                            //获取流对象
                            GridFsResource gridFsResource = new GridFsResource(gridFSFile, downloadStream);


                            //添加日期目录
                            String format = sdf.format(new Date());
                            //指定本地文件夹存储图片
                            String filePathDir = "D:/images/" + format;
                            File fileDir = new File(filePathDir);
                            String filePath = "D:/images/" + format + "/1.jpg";
                            File targetFile = new File(filePath);
                            FileUtils.copyInputStreamToFile(gridFsResource.getInputStream(), targetFile);

                            try {
                                FileInputStream in = null;
                                in = ImageUtil.readImage(filePath);
                                String sql_update = "UPDATE " + layername + " SET  " + formcontentname_ + "='" + in + "' WHERE id= '" + gid + "'";
                                toolsResposity.exeSql(sql_update);
                                targetFile.delete();
                                fileDir.delete();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            System.out.println("打印文件:" + s);
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            } else {

                String value = "";
                for (int j = 0; j < id_list.size(); j++) {
                    Map mapIds = (Map) id_list.get(j);
                    String id = mapIds.get("id").toString();//mongodb中的globle_edit_geoid
                    String gid = mapIds.get("gid").toString();//t_subtask_geom中的gid也是sick_tree中的id
                    //去mongodb中查找
                    Criteria criteria = Criteria.where("metadata.globle_edit_geoid").is(id);
                    Query query = new Query(criteria);
                    Map contentMap = mongoTemplate.findOne(query, JSONObject.class, "tableEntity");
                    if (contentMap != null) {
                        value = contentMap.get(formcontentname).toString();
                        //插入t_subtask_geom表数据
                        String sql_update = "UPDATE " + layername + " SET  " + formcontentname + "='" + value + "' WHERE id= '" + gid + "'";
                        toolsResposity.exeSql(sql_update);
                    }

                }
            }


        }
    }

    @Override
    public Map queryTables(String subtaskid, String caseid) {

        JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(SecurityUtils.getUsername());
        Long userid = jwtUser.getId();

        Map returnMap = new HashMap();
        //结构
        String sql = "select * from t_form_content where formid in (SELECT formid FROM public.t_case_form where caseid = '" + caseid + "')";
        List structList = toolsResposity.exeSqlList(sql);
        returnMap.put("struct", structList);

        //内容

        Criteria criteria = Criteria.where("metadata.globle_subtaskid").is(subtaskid);
        criteria.and("metadata.globle_userid").is(userid);
        Query query = new Query(criteria);
        List contentList = mongoTemplate.find(query, JSONObject.class, "tableEntity");
        if (contentList.size() == 0) {
            returnMap.put("hasContent", false);
        } else {
            returnMap.put("hasContent", true);
        }
        returnMap.put("content", contentList);

        return returnMap;
    }

    @Override
    public Map getSubTasksMongoDb(String taskid, String caseid) {

        JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(SecurityUtils.getUsername());
        Long userid = jwtUser.getId();

        //select layerid from t_case_layer where caseid in (select caseid from t_task where id = sss)
        Map returnMap = new HashMap();
        List subList = new ArrayList();
        String sql = "select * from t_subtask where taskid in (" + taskid + ") and userid = " + userid;
        List subtaskList = toolsResposity.exeSqlList(sql);
        for (int i = 0; i < subtaskList.size(); i++) {
            Map subTaskMap = (Map) subtaskList.get(i);
            String subtaskid = subTaskMap.get("id").toString();
            //查询范围pg
            String polygonSql = "SELECT * FROM public.t_subtask_polygon where subtaskid = '" + subtaskid + "'";
            List listExtent = toolsResposity.exeSqlList(polygonSql);
            subTaskMap.put("extent", listExtent);
            //查询相交图斑mongodb
            Query query = new Query(Criteria.where("subtaskid").is(Integer.parseInt(subtaskid)));
            List listGeom = mongoTemplate.find(query, GeomEntity.class);
            List listGeomAndTable = new ArrayList();
            List listNewGeomAndTable = new ArrayList();//新的图斑
            for (int j = 0; j < listGeom.size(); j++) {
                GeomEntity geomEntity = (GeomEntity) listGeom.get(j);

                boolean isCreated = geomEntity.isCreated();
                //原来就有的图斑
                if (!isCreated) {
                    int gid = geomEntity.getGid();
                    Criteria criteria = Criteria.where("metadata.globle_subtaskid").is(subtaskid);
                    criteria.and("metadata.globle_gid").is(gid + "");
                    criteria.and("metadata.globle_userid").is(Integer.parseInt(userid + ""));
                    Query query1 = new Query(criteria);
                    JSONObject jsonObject = mongoTemplate.findOne(query1, JSONObject.class, "tableEntity");
                    if (jsonObject != null) {
                        System.out.println(jsonObject.toJSONString());
                    }
                    geomEntity.setTable(jsonObject);
                    listGeomAndTable.add(geomEntity);
                } else {
                    Map newGeomMap = geomEntity.getNewGeom();
                    String polygon = newGeomMap.get("polygon").toString();
                    String gid = newGeomMap.get("gid").toString();
                    String type = newGeomMap.get("type").toString();
                    Map tempMap = new HashMap();
                    tempMap.put("type", type);
                    tempMap.put("geo", polygon);
                    tempMap.put("gid", gid);
                    tempMap.put("table", geomEntity.getTable());
                    String multiStr = "POLYGON((" + polygon + "))";
                    try {
                        String sql_temp = "SELECT ST_AsText(ST_Centroid('" + multiStr + "'))";
                        Map centerMap = toolsResposity.exeSql(sql_temp);
                        String center = centerMap.get("st_astext").toString();
                        center = center.substring(6, center.length() - 1);
                        tempMap.put("center", center);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    listNewGeomAndTable.add(tempMap);
                }

            }

            subTaskMap.put("editPolygon", transToWkt(listGeomAndTable));
            subTaskMap.put("newPolygon", listNewGeomAndTable);
            subList.add(subTaskMap);
        }

        String layerSql = "select * from t_layer where id in (select layerid from t_case_layer where caseid = '" + caseid + "')";
        List layerList = toolsResposity.exeSqlList(layerSql);
        returnMap.put("subtask", subList);
        returnMap.put("layers", layerList);
        return returnMap;
    }

    public List transToWktWithField(List listGemo) {

        List returnList = new ArrayList();
        for (int i = 0; i < listGemo.size(); i++) {
            Map geomEntity = (Map) listGemo.get(i);
            String gid = geomEntity.get("gid").toString();
            String layername = geomEntity.get("layername").toString();
            String sql = "select * from " + layername + " where id = '" + gid + "'";
            Map orgTable = toolsResposity.exeSql(sql);

            String st_astext = geomEntity.get("st_astext").toString();
            boolean iscreated = (boolean) geomEntity.get("iscreated");
            String edit_geoid = geomEntity.get("id").toString();
            Map tableMap = (Map) geomEntity.get("table");

            Map geoMap = filterGeo(edit_geoid, iscreated, st_astext);
            geoMap.put("table", tableMap);
            geoMap.put("orgTable", orgTable);
            returnList.add(geoMap);
        }
        return returnList;
    }

    public List transToWkt(List listGemo) {

        List returnList = new ArrayList();
        for (int i = 0; i < listGemo.size(); i++) {
            Map geomEntity = (Map) listGemo.get(i);

            String st_astext = geomEntity.get("st_astext").toString();
            boolean iscreated = (boolean) geomEntity.get("iscreated");
            String edit_geoid = geomEntity.get("id").toString();
            Map tableMap = (Map) geomEntity.get("table");

            Map geoMap = filterGeo(edit_geoid, iscreated, st_astext);
            geoMap.put("table", tableMap);
            returnList.add(geoMap);
        }
        return returnList;
    }

    public List transToWktMongoDb(List listGemo) {

        List returnList = new ArrayList();
        for (int i = 0; i < listGemo.size(); i++) {
            GeomEntity geomEntity = (GeomEntity) listGemo.get(i);
            JSONObject jsonObject = geomEntity.getTable();
            String geojson = geomEntity.getGeojson();

            cn.hutool.json.JSONObject json = (cn.hutool.json.JSONObject) JSONUtil.parseObj(geojson);
            String gid = json.get("gid").toString();
            json.remove("gid");
            cn.hutool.json.JSONObject geometryJson = (cn.hutool.json.JSONObject) json.get("geometry");
            geometryJson.remove("crs");
            System.out.println("WKT 转 Feature：" + GeoTools.geoJsonToWkt(json));

            Map geoMap = filterGeo(null, false, GeoTools.geoJsonToWkt(json));
            geoMap.put("table", jsonObject);
            returnList.add(geoMap);
        }
        return returnList;
    }

    /**
     * 过滤geom字段
     *
     * @param
     * @return
     */
    private Map filterGeo(String edit_geoid, boolean iscreated, String st_astext) {

        String multiStr = st_astext;

        Map map = new HashMap();
        List listPolygon = new ArrayList();

        if (st_astext.contains("MULTIPOLYGON")) {
            st_astext = st_astext.substring(15, st_astext.length() - 3);

            String[] polygons = st_astext.split("\\)\\),\\(\\(");

            for (int j = 0; j < polygons.length; j++) {
                String polygon = polygons[j].trim();
                if (polygon.contains("),(")) {
                    String[] polygonHole = polygon.split("\\),\\(");
                    listPolygon.add(polygonHole);
                } else {
                    listPolygon.add(polygon);
                }
            }
            map.put("iscreated", iscreated);
            map.put("edit_geoid", edit_geoid);
            map.put("geo", listPolygon);
            map.put("geotype", "polygon");

            try {
                String sql = "SELECT ST_AsText(ST_Centroid('" + multiStr + "'))";
                Map centerMap = toolsResposity.exeSql(sql);
                String center = centerMap.get("st_astext").toString();
                center = center.substring(6, center.length() - 1);
                map.put("center", center);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (st_astext.contains("POLYGON")) {
            st_astext = st_astext.substring(9, st_astext.length() - 2);
            map.put("iscreated", iscreated);
            map.put("edit_geoid", edit_geoid);
            map.put("geo", st_astext);
            map.put("geotype", "polygon");
        } else {
            st_astext = st_astext.substring(6, st_astext.length() - 2);

            map.put("iscreated", iscreated);
            map.put("edit_geoid", edit_geoid);
            map.put("geo", st_astext);
            map.put("geotype", "point");
        }


        return map;
    }


    public String saveFile(File file, String fileid, String formcontentname, String globle_userid, String globle_subtaskid, String globle_edit_geoid,
                           String alpha, String beta, String gamma, String lat, String lon) {
        String filename = null;
        try {
            // 设置meta数据值
            Map<String, String> metaData = new HashMap<>();
            metaData.put("globle_userid", globle_userid);
            metaData.put("globle_subtaskid", globle_subtaskid);
            metaData.put("globle_edit_geoid", globle_edit_geoid);
            metaData.put("globle_formcontentname", formcontentname);
            metaData.put("filename", fileid);
            metaData.put("alpha", alpha);
            metaData.put("beta", beta);
            metaData.put("gamma", gamma);
            metaData.put("lat", lat);
            metaData.put("lon", lon);


            FileInputStream fileInputStream = new FileInputStream(file);//与根据File类对象的所代表的实际文件建立链接创建fileInputStream对象

            // 获取文件的源名称
            String fileName = file.getAbsoluteFile().getName();
            // 进行文件存储
            ObjectId objectId = gridFsTemplate.store(fileInputStream, fileName, metaData);

            //查询filename,根据objectId
            Criteria criteria = Criteria.where("_id").is(objectId.toString());
            Query query = new Query(criteria);
            GridFSFile gridFSFile = gridFsTemplate.findOne(query);
            Map map = gridFSFile.getMetadata();
            filename = map.get("filename").toString();
            System.out.println(objectId);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("存储文件时发生错误！！！");
        }

        return filename;
    }


    public String saveVideo(File file, String fileid, String formcontentname, String globle_userid, String globle_subtaskid, String globle_edit_geoid) {
        String video = null;
        try {
            // 设置meta数据值
            Map<String, String> metaData = new HashMap<>();
            metaData.put("globle_userid", globle_userid);
            metaData.put("globle_subtaskid", globle_subtaskid);
            metaData.put("globle_edit_geoid", globle_edit_geoid);
            metaData.put("globle_formcontentname", formcontentname);
            metaData.put("video", fileid);


            FileInputStream fileInputStream = new FileInputStream(file);//与根据File类对象的所代表的实际文件建立链接创建fileInputStream对象

            // 获取文件的源名称
            String videoName = file.getAbsoluteFile().getName();
            // 进行文件存储
            ObjectId objectId = gridFsTemplate.store(fileInputStream, videoName, metaData);

            //查询filename,根据objectId
            Criteria criteria = Criteria.where("_id").is(objectId.toString());
            Query query = new Query(criteria);
            GridFSFile gridFSFile = gridFsTemplate.findOne(query);
            Map map = gridFSFile.getMetadata();
            video = map.get("videoName").toString();
            System.out.println(objectId);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("存储文件时发生错误！！！");
        }

        return video;
    }

    /**
     * @return
     * @Author zxw
     * @Description //TODO 查询指定任务中所有已核查的图斑(globle_status字段为已核实) 传入参数	{taskid:97}
     * @Date 2023/10/24  15:27
     **/
    @Override
    public List getCheckedPolygonByTaskId(Integer taskid) {
        String sql = String.format("SELECT id, subtaskid, taskid,\n" +
                "       CASE\n" +
                "           WHEN ST_GeometryType(geom) = 'ST_Multipolygon' THEN TRIM(both 'MULTIPOLYGON(((' from regexp_replace(ST_AsText(geom), '\\)\\)\\)', ''))\n" +
                "           WHEN ST_GeometryType(geom) = 'ST_Polygon' THEN TRIM(both 'POLYGON((' FROM REGEXP_REPLACE(ST_AsText(geom), '\\)\\)', ''))\n" +
                "           WHEN ST_GeometryType(geom) = 'ST_Point' THEN TRIM(both 'POINT((' FROM REGEXP_REPLACE(ST_AsText(geom), '\\)', ''))\n" +
                "           ELSE 'Invalid Geometry Type'\n" +
                "       END AS geo\n" +
                "from t_subtask_geom where taskid in (select taskid from t_subtask where status='已核实' and taskid=%d); ", taskid);
        return toolsResposity.exeSqlList(sql);
    }

    @Override
    public List queryById(String id, String taskid) {
        return null;
    }

    @Override
    public List queryByDraw(String json) {
        return null;
    }

    @Override
    public List queryByTimeAndTaskId(LocalDateTime startTime, LocalDateTime endTime, String taskid) {
        return null;
    }

    @Override
    public void deleteVideoFile(String subtaskid, String filename) {

    }

    @Override
    public List<SubtaskGeom> queryUnCheckedByTaskId(Integer taskid) {
        return null;
    }
}

